package com.jinzhi.jzapi.examination.task;

import com.jinzhi.jzweb.domain.ExaminationBatchDO;
import com.jinzhi.jzweb.service.ExaminationBatchService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.crypto.Cipher;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Slf4j
@Component
public class AutoExaminStateJob implements Job {

    @Autowired
    private ExaminationBatchService examinationBatchService;

    @Override
    @Transactional
    public void execute(JobExecutionContext jobExecutionContext){
        log.info("---------------------开始查询信息---------------------");
        fixKeyLength();
        //查询所有考试批次
        List<ExaminationBatchDO> examinationBatchDOS = examinationBatchService.findByKv();
        if(examinationBatchDOS != null && examinationBatchDOS.size() > 0){
            for(ExaminationBatchDO examinationBatchDO : examinationBatchDOS){
                Date date = new Date();

                //小于考试开始时间，小于考试结束时间：还未考试
                if(date.after(examinationBatchDO.getStartTime()) && date.before(examinationBatchDO.getEndTime())){//大于考试开始时间，小于考试结束时间：考试中
                    if(examinationBatchDO.getState().equals(1) || examinationBatchDO.getState().equals(3) || examinationBatchDO.getState().equals(6)){
                        examinationBatchDO.setState(4);
                        examinationBatchService.updateById(examinationBatchDO);
                    }
                }else if(date.after(examinationBatchDO.getStartTime()) && date.after(examinationBatchDO.getEndTime())){//大于考试开始时间，大于考试结束时间：已考完
                    examinationBatchDO.setState(5);
                    examinationBatchService.updateById(examinationBatchDO);
                }

            }
        }
    }

    static void fixKeyLength() {
        String errorString = "Failed manually overriding key-length permissions.";
        int newMaxKeyLength;
        try {
            if ((newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) {
                Class c = Class.forName("javax.crypto.CryptoAllPermissionCollection");
                Constructor con = c.getDeclaredConstructor();
                con.setAccessible(true);
                Object allPermissionCollection = con.newInstance();
                Field f = c.getDeclaredField("all_allowed");
                f.setAccessible(true);
                f.setBoolean(allPermissionCollection, true);

                c = Class.forName("javax.crypto.CryptoPermissions");
                con = c.getDeclaredConstructor();
                con.setAccessible(true);
                Object allPermissions = con.newInstance();
                f = c.getDeclaredField("perms");
                f.setAccessible(true);
                ((Map) f.get(allPermissions)).put("*", allPermissionCollection);

                c = Class.forName("javax.crypto.JceSecurityManager");
                f = c.getDeclaredField("defaultPolicy");
                f.setAccessible(true);
                Field mf = Field.class.getDeclaredField("modifiers");
                mf.setAccessible(true);
                mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
                f.set(null, allPermissions);

                newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES");
            }
        } catch (Exception e) {
            throw new RuntimeException(errorString, e);
        }
        if (newMaxKeyLength < 256)
            throw new RuntimeException(errorString); // hack failed
    }

}
